# 导入Django模块
import logging
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from django.contrib import messages

# 导入模型
from core.models.mistake import Mistake
from core.models.subject import Subject
from core.models.knowledge_point import KnowledgePoint
from core.models.chapter import Chapter
from django.contrib.auth.models import User

# 导入表单和工具
from core.forms.mistake_form import MistakeForm
from core.utils import log_operation

# 配置日志
logger = logging.getLogger(__name__)
@login_required
def mistake_list(request):
    """
    错题列表视图
    
    参数:
        request: HTTP请求对象，可能包含筛选参数
    
    返回:
        渲染的错题列表页面
    """
    try:
        # 获取筛选参数
        search_key = request.GET.get("search", "")
        subject_id = request.GET.get("subject", "")
        teacher_id = request.GET.get("teacher", "")
        chapter_id = request.GET.get("chapter", "")
        knowledge_point_id = request.GET.get("knowledge_point", "")
        star_level = request.GET.get("star_level", "")

        # 构建查询集并预加载相关模型
        mistakes = Mistake.objects.filter(create_by=request.user).select_related(
            "subject", "chapter", "knowledge_point"
        )

        # 应用搜索筛选
        if search_key:
            mistakes = mistakes.filter(
                Q(title__icontains=search_key) |
                Q(description__icontains=search_key) |
                Q(solution__icontains=search_key)
            )

        # 应用其他筛选条件
        filters = {
            'subject_id': subject_id,
            'create_by_id': teacher_id,
            'chapter_id': chapter_id,
            'knowledge_point_id': knowledge_point_id,
            'star_level': star_level
        }
        # 移除空值筛选
        filters = {k: v for k, v in filters.items() if v}
        if filters:
            mistakes = mistakes.filter(**filters)

        # 排序
        mistakes = mistakes.order_by("-created_at")

        # 获取筛选选项数据
        subjects = Subject.objects.all()
        teachers = User.objects.all()
        chapters = Chapter.objects.all() if not subject_id else Chapter.objects.filter(subject_id=subject_id)
        knowledge_points = KnowledgePoint.objects.all() if not chapter_id else KnowledgePoint.objects.filter(chapter_id=chapter_id)
        star_levels = [(i, f'{i}星') for i in range(1, 6)]

        # 渲染错题列表页面
        context = {
            "mistakes": mistakes,
            "search_key": search_key,
            "subjects": subjects,
            "subject_id": subject_id,
            "teachers": teachers,
            "teacher_id": teacher_id,
            "chapters": chapters,
            "chapter_id": chapter_id,
            "knowledge_points": knowledge_points,
            "knowledge_point_id": knowledge_point_id,
            "star_levels": star_levels,
            "star_level": star_level
        }
        return render(request, "mistake/mistake_list.html", context)
    except Exception as e:
        logger.error(f"错题列表加载失败: {str(e)}", exc_info=True)
        messages.error(request, f"错题列表加载失败: {str(e)}")
        return render(request, "mistake/mistake_list.html", {})




def _get_initial_context(knowledge_point_id):
    """获取初始表单上下文数据"""
    initial_data = {}
    initial_subject = None
    initial_chapter = None
    initial_knowledge_point = None

    if knowledge_point_id:
        initial_data = {"knowledge_point": knowledge_point_id}
        try:
            initial_knowledge_point = KnowledgePoint.objects.select_related('chapter').get(id=knowledge_point_id)
            initial_chapter = initial_knowledge_point.chapter
            initial_subject = initial_chapter.subject
        except KnowledgePoint.DoesNotExist:
            pass

    subjects = Subject.objects.all()
    return initial_data, subjects, initial_subject, initial_chapter, initial_knowledge_point

@login_required
def mistake_create(request):
    """
    创建新的错题
    
    参数:
        request: HTTP请求对象，可能包含知识点ID参数
    
    返回:
        GET请求: 渲染的错题创建表单页面
        POST请求: 重定向到错题列表页面(创建成功)或重新渲染表单(创建失败)
    """
    try:
        # 获取知识点ID并准备初始数据
        knowledge_point_id = request.GET.get("knowledge_point_id") or request.POST.get("knowledge_point")
        initial_data, subjects, initial_subject, initial_chapter, initial_knowledge_point = _get_initial_context(knowledge_point_id)

        if request.method == "POST":
            # 处理表单提交
            form = MistakeForm(request.POST, initial=initial_data)
            if form.is_valid():
                # 表单验证通过，创建错题对象但不保存到数据库
                mistake = form.save(commit=False)
                # 设置错题的创建者为当前用户
                mistake.create_by = request.user
                # 从知识点获取学科和章节信息
                knowledge_point = form.cleaned_data['knowledge_point']
                mistake.chapter = knowledge_point.chapter
                mistake.subject = knowledge_point.chapter.subject
                # 保存错题到数据库
                mistake.save()
                # 记录操作日志
                log_operation(
                    user=request.user,
                    operation_type='create',
                    content_type='Mistake',
                    object_id=mistake.id,
                    object_name=mistake.title,
                    request=request,
                    details=f'创建错题: {mistake.title}'
                )
                messages.success(request, "错题创建成功！")
                # 重定向到错题列表页面
                return redirect("core:mistake_list")
            else:
                messages.warning(request, "表单验证失败，请检查输入内容。")
        else:
            # GET请求初始化表单
            form = MistakeForm(initial=initial_data)

        # 渲染错题创建表单，并传递必要的上下文数据
        return render(
            request,
            "mistake/mistake_form.html",
            {
                "form": form,
                "subjects": subjects,
                "initial_subject": initial_subject,
                "initial_chapter": initial_chapter,
                "initial_knowledge_point": initial_knowledge_point,
                "is_update": False
            },
        )
    except Exception as e:
        logger.error(f"创建错题失败: {str(e)}", exc_info=True)
        messages.error(request, f"创建错题失败: {str(e)}")
        return redirect("core:mistake_list")




@login_required
def mistake_update(request, pk):
    """
    更新错题
    
    参数:
        request: HTTP请求对象
        pk: 错题ID
    
    返回:
        GET请求: 渲染的错题编辑表单页面
        POST请求: 重定向到错题列表页面(更新成功)或重新渲染表单(更新失败)
    """
    try:
        # 获取当前用户的指定错题，如果不存在则返回404错误
        mistake = get_object_or_404(Mistake, pk=pk, create_by=request.user)
        if request.method == "POST":
            # 处理表单提交
            form = MistakeForm(request.POST, instance=mistake)
            if form.is_valid():
                # 表单验证通过，更新错题对象但不保存到数据库
                mistake = form.save(commit=False)
                # 确保创建者仍然是当前用户
                mistake.create_by = request.user
                # 从知识点获取学科和章节信息
                knowledge_point = form.cleaned_data['knowledge_point']
                mistake.chapter = knowledge_point.chapter
                mistake.subject = knowledge_point.chapter.subject
                # 保存更新后的错题到数据库
                mistake.save()
                # 记录操作日志
                log_operation(
                    user=request.user,
                    operation_type='update',
                    content_type='Mistake',
                    object_id=mistake.id,
                    object_name=mistake.title,
                    request=request,
                    details=f'更新错题: {mistake.title}'
                )
                messages.success(request, "错题更新成功！")
                # 重定向到错题列表页面
                return redirect("core:mistake_list")
            else:
                messages.warning(request, "表单验证失败，请检查输入内容。")
        else:
            # GET请求，使用现有错题数据初始化表单
            form = MistakeForm(instance=mistake)

        # 获取上下文数据
        initial_knowledge_point = mistake.knowledge_point
        initial_chapter = initial_knowledge_point.chapter
        initial_subject = initial_chapter.subject
        subjects = Subject.objects.all()

        # 渲染错题编辑表单，并传递必要的上下文数据
        return render(
            request,
            "mistake/mistake_form.html",
            {
                "form": form,
                "subjects": subjects,
                "initial_subject": initial_subject,
                "initial_chapter": initial_chapter,
                "initial_knowledge_point": initial_knowledge_point,
                "is_update": True,
                "mistake": mistake
            },
        )
    except Exception as e:
        logger.error(f"更新错题失败: {str(e)}", exc_info=True)
        messages.error(request, f"更新错题失败: {str(e)}")
        return redirect("core:mistake_list")




@login_required
def mistake_delete(request, pk):
    """
    删除指定的错题
    
    参数:
        request: HTTP请求对象
        pk: 错题的主键ID
    
    返回:
        GET请求: 渲染的确认删除页面
        POST请求: 重定向到错题列表页面(删除成功)
    """
    try:
        # 获取当前用户的指定错题，如果不存在则返回404错误
        mistake = get_object_or_404(Mistake, pk=pk, create_by=request.user)
        if request.method == "POST":
            # 记录要删除的错题信息
            mistake_title = mistake.title
            mistake_id = mistake.id
            # 删除错题
            mistake.delete()
            # 记录操作日志
            log_operation(
                user=request.user,
                operation_type='delete',
                content_type='Mistake',
                object_id=mistake_id,
                object_name=mistake_title,
                request=request,
                details=f'删除错题: {mistake_title}'
            )
            messages.success(request, "错题删除成功！")
            # 重定向到错题列表页面
            return redirect("core:mistake_list")
        # GET请求，渲染确认删除页面
        return render(request, "mistake/mistake_confirm_delete.html", {"mistake": mistake})
    except Exception as e:
        logger.error(f"删除错题失败: {str(e)}", exc_info=True)
        messages.error(request, f"删除错题失败: {str(e)}")
        return redirect("core:mistake_list")




# 导入缺失的知识点模型
from core.models.knowledge_point import KnowledgePoint

